package com.hxexp.weixin.mvc.login.service.impl;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.hxexp.weixin.common.cache.TokenCacheManager;
import com.hxexp.weixin.common.exception.APIException;
import com.hxexp.weixin.common.exception.ServiceException;
import com.hxexp.weixin.common.math.RandomUtil;
import com.hxexp.weixin.common.web.CookieUtil;
import com.hxexp.weixin.constant.CookieName;
import com.hxexp.weixin.constant.Errcode;
import com.hxexp.weixin.constant.LoginType;
import com.hxexp.weixin.hpe.api.addbind.AddBindAPI;
import com.hxexp.weixin.hpe.api.addbind.model.AddBindParamBean;
import com.hxexp.weixin.hpe.api.addbind.model.AddBindResultBean;
import com.hxexp.weixin.hpe.api.delbind.DelBindAPI;
import com.hxexp.weixin.hpe.api.delbind.model.DelBindParamBean;
import com.hxexp.weixin.hpe.api.delbind.model.DelBindResultBean;
import com.hxexp.weixin.hpe.api.login.LoginAPI;
import com.hxexp.weixin.hpe.api.login.model.LoginParamBean;
import com.hxexp.weixin.hpe.api.login.model.LoginResultBean;
import com.hxexp.weixin.mvc.login.service.LoginService;

/**
 * 登录服务实现类
 * @author li.jiang
 *
 */
@Service
public final class LoginServiceImpl implements LoginService {
    private static final int COOKIE_MAX_AGE = 1800; // cookie有效时间30分钟

    @Autowired
    private TokenCacheManager tokenCacheManager;
    @Autowired
    private LoginAPI loginAPI;
    @Autowired
    private AddBindAPI addBindAPI;
    @Autowired
    private DelBindAPI delBindAPI;
    /* (non-Javadoc)
     * @see com.hxexp.weixin.mvc.login.service.LoginService#verifyLogin(java.lang.String, java.lang.String)
     */
    @Override
    public LoginResultBean loginByUsername(String username, String password) throws ServiceException {
        LoginResultBean loginResult = new LoginResultBean();

        try {
            loginResult = loginAPI.login(new LoginParamBean(username, password, LoginType.LOGIN_BY_USER, null));
        } catch (APIException e) {
            throw new ServiceException(e);
        }
        return loginResult;
    }

    /* (non-Javadoc)
     * @see com.hxexp.weixin.mvc.login.service.LoginService#rememberLoginUser(com.hxexp.weixin.model.hpe.login.LoginResultBean)
     */
    @Override
    public String rememberLoginUser(LoginResultBean userLoginInfo, HttpServletResponse response) {
        // 生成登录token
        String token = RandomUtil.getUUID();
        // 保存登录用户信息
        tokenCacheManager.saveUserToCache(token, userLoginInfo);
        // 将登录token值写入到客户端
        CookieUtil.addCookie(response, CookieName.TOKEN, token, COOKIE_MAX_AGE);
        return token;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.hxexp.weixin.mvc.login.service.LoginService#loginByOpenId(java.lang.String)
     */
    @Override
    public LoginResultBean loginByOpenId(String openid) throws ServiceException {
        LoginResultBean loginResult = new LoginResultBean();

        try {
            loginResult = loginAPI.login(new LoginParamBean(null, null, LoginType.LOGIN_BY_OPENID, openid));
        } catch (APIException e) {
            throw new ServiceException(e);
        }
        return loginResult;
    }

    /*
     * (non-Javadoc)
     *
     * @see com.hxexp.weixin.mvc.login.service.LoginService#addOpenIdBind(com.hxexp.weixin.hpe.api.addbind.model.
     * AddBindParamBean)
     */
    @Async
    @Override
    public void addOpenIdBind(LoginResultBean userLoginInfo, String openid) throws ServiceException {
        if (!StringUtils.isEmpty(openid)) {
            if (!StringUtils.isEmpty(userLoginInfo.getOpenId())) {
                delBind(userLoginInfo);
            }

            addBind(userLoginInfo, openid);
        }
    }

    // 删除绑定
    private void delBind(LoginResultBean userLoginInfo) throws ServiceException {
        DelBindParamBean delBindParam = new DelBindParamBean();
        delBindParam.setOpenId(userLoginInfo.getOpenId());

        try {
            DelBindResultBean delBindResult = delBindAPI.delBind(delBindParam);

            if (delBindResult.getErrcode() != Errcode.SUCCESS) {
                throw new APIException("解除微信用户与HPE绑定关系失败！");
            }
        } catch (APIException e) {
            throw new ServiceException(e);
        }
    }

    // 添加绑定
    private void addBind(LoginResultBean userLoginInfo, String openid) throws ServiceException {
        AddBindParamBean addBindParam = new AddBindParamBean();
        addBindParam.setUserId(userLoginInfo.getUserId());
        addBindParam.setOpenId(openid);

        try {
            AddBindResultBean addBindResult = addBindAPI.addBind(addBindParam);
            if (addBindResult.getErrcode() != Errcode.SUCCESS) {
                throw new APIException("添加微信用户与HPE绑定关系失败！");
            }
        } catch (APIException e) {
            throw new ServiceException(e);
        }
    }
}
